package com.mcms.web.service;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import com.mcms.util.DBHelper;
import com.mcms.web.vo.DictCache;
import com.mcms.web.vo.PropertyObject;
import com.mcms.web.vo.TransCache;
import com.mcms.web.vo.TransObject;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

public class LoadServiceListener implements ServletContextListener {
	private boolean status = true;// 监听状态
	private long lastModify_time; // 修改时间

	public LoadServiceListener() {
		super();
	}

	public void contextDestroyed(ServletContextEvent arg0) {
		// TODO Auto-generated method stub
		this.status = false;
	}

	/*
	 * 监听启动：读取transInput.xml文件，解析并加载至TaskInfo寄存器和quartz任务列表中
	 * 
	 * @see
	 * javax.servlet.ServletContextListener#contextInitialized(javax.servlet
	 * .ServletContextEvent)
	 */
	public void contextInitialized(ServletContextEvent arg0) {
		System.out.println("****************自动将数据字典项加载至cache中********************");
		DictCache.getInstance().load();
		

		System.out.println("****************Trans监听正常启动********************");

		// 获取配置文件(transInput.xml)的路径，并生成file文件
		File varFile = null;
		String varFilePath = Thread.currentThread().getContextClassLoader()
				.getResource("").getPath() + "transInput.xml";
		varFile = new File(varFilePath);

		// 解析定时任务配置文件，加载job内容至内存
		parseXml(varFile);

		// 启动守护线程，轮询transInput.xml，是否被修改;被修改则自动重新加载
		new Thread(new ListenerXml(varFile)).start();
	}
	
	/**
	 * 加载字典表中的数据至cache中
	 */
	public void loadDictDate(){
		String sqlStr = "select DICT_TYPE,DICT_CODE,DICT_NAME,DICT_ORDER from mcms_com_dict order by dict_type,dict_order";
		DBHelper dbh = DBHelper.getInstance();
		List listResult = dbh.query(sqlStr);
		String key = "";
		String value = "";
		Map outSideMap = new HashMap();
		
		for(int i=0; i<listResult.size(); i++){
			Map<String, String> map = (Map<String, String>) listResult.get(i);
			map.get("DICT_TYPE");
			map.get("DICT_CODE");
			map.get("DICT_NAME");
			if(!outSideMap.containsKey(map.get("DICT_TYPE"))){
				Map treeMap = new TreeMap();
				treeMap.put(map.get("DICT_CODE"), map.get("DICT_NAME"));
				outSideMap.put(map.get("DICT_TYPE"), treeMap);
			}else{
//				Map treeMap = (Map) outSideMap.get(map.get("DICT_TYPE"));
				((Map) outSideMap.get(map.get("DICT_TYPE"))).put(map.get("DICT_CODE"), map.get("DICT_NAME"));
			}
		}
	}

	/**
	 * 解析配置文件(transInput.xml)，并将trans加载至内存
	 * 
	 * @param varFile
	 *            配置文件对象
	 */
	public void parseXml(File varFile) {
		InputStream is = null;
		lastModify_time = varFile.lastModified();// 最后修改的时间

		// 首先读取ruleConstant.xml文件中的规则变量配置
		if (varFile.exists() && varFile.isFile()) {
			System.out.println("transInput.xml文件存在");

			try {
				is = new FileInputStream(varFile);
				DocumentBuilder db = DocumentBuilderFactory.newInstance()
						.newDocumentBuilder();
				Document doc = db.parse(is);
				Element root = doc.getDocumentElement();
				NodeList nodeList;
				NodeList nl;
				Element element, elm;
				Map pm = new HashMap();// property的map
				PropertyObject proObj;// 属性对象
				List pList;// 属性列表
				Map tm = new HashMap();// trans对象的map(key=transId,value=transobject)
				TransCache transInfo = TransCache.getInstance();
				TransObject transObj;

				// 读取Trans节点,将所有trans对象加载入内存
				String transId;
				nodeList = root.getElementsByTagName("transaction");
				for (int i = 0; i < nodeList.getLength(); i++) {
					transObj = new TransObject();
					pList = new ArrayList();
					element = (Element) nodeList.item(i);

					// 组织trans对象
					transId = element.getAttribute("id");
					transObj.setTransId(transId);
					transObj.setTransName(element.getAttribute("name"));
					transObj.setCheckPoint(element.getAttribute("checkpoint"));
					transObj.setTransationType(element
							.getAttribute("transactionType"));
					transObj.setIsLogin(Boolean.parseBoolean(element
							.getAttribute("isLogin")));
					transObj.setCount(element.getAttribute("count"));

					// 解析trans的property列表
					nl = element.getElementsByTagName("property");
					for (int j = 0; j < nl.getLength(); j++) {
						elm = (Element) nl.item(j);

						// 组织property对象(每个trans对象有多个property对象)
						proObj = new PropertyObject();
						proObj.setId(elm.getAttribute("id"));
						proObj.setName(elm.getAttribute("name"));
						proObj.setCname(elm.getAttribute("cname"));
						proObj.setInput(elm.getAttribute("input"));
						proObj.setType(elm.getAttribute("type"));
						proObj.setValue(elm.getAttribute("value"));
						proObj.setTransname(elm.getAttribute("transname"));

						// 将property对象放入proList中
						pList.add(proObj);// 将property放入list
					}

					// 将proList放入trans对象中(proList是trans对象的其中一个属性)
					transObj.setProObjList(pList);

					// 将trans对象放入transmap中
					tm.put(transId, transObj);

				}

				// 将tmap放入寄存器中
				transInfo.putObject(tm);

			} catch (FileNotFoundException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (ParserConfigurationException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (SAXException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

	/**
	 * 
	 * 轮询transInput.xml文件的线程
	 * 
	 */
	private class ListenerXml implements Runnable {
		private File file;

		public ListenerXml(File file) {
			this.file = file;
		}

		public void run() {
			// TODO Auto-generated method stub
			while (status) {// 轮询xml文件

				try {
					long time1 = file.lastModified();
					if (time1 != lastModify_time) {
						 System.out.println("*********************transInput.xml文件被修改！*************************");
						TransCache transInfo = TransCache.getInstance();

						// 移除transObject寄存器中所有的内容
						transInfo.removeAllObjects();

						// 重新解析配置文件并加载
						parseXml(file);
						lastModify_time = time1;
					}

					// 休眠20毫秒，避免死循环
					Thread.sleep(20);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
	}
}
